library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 3.5.1 ✔ tibble 3.2.1
## ✔ lubridate 1.9.4 ✔ tidyr 1.3.1
## ✔ purrr 1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(Seurat)
## Loading required package: SeuratObject
## Loading required package: sp
##
## Attaching package: 'SeuratObject'
##
## The following objects are masked from 'package:base':
##
## intersect, t
library(Signac)
library(patchwork)
library(hexpression)
rna_datasets_paths <- list(
dpf1.5 = "data/RNA/1.5dpf_scRNA.rds",
dpf2 = "data/RNA/2dpf_scRNA.rds",
dpf3 = "data/RNA/3dpf_scRNA.rds",
dpf5 = "data/RNA/5dpf_scRNA.rds",
dpf14 = "data/RNA/14dpf_scRNA.rds",
dpf60 = "data/RNA/60dpf_scRNA.rds",
dpf150 = "data/RNA/150dpf_scRNA.rds"
)
rna_datasets <- lapply(rna_datasets_paths, readRDS)
atac_datasets_paths <- list(
dpf1.5 = "data/ATAC/1.5dpf_snATAC_SnapATAC.rds",
dpf2 = "data/ATAC/2dpf_snATAC_SnapATAC.rds",
dpf3 = "data/ATAC/3dpf_snATAC_SnapATAC.rds",
dpf5 = "data/ATAC/5dpf_snATAC_SnapATAC.rds",
dpf14 = "data/ATAC/14dpf_snATAC_SnapATAC.rds",
dpf60 = "data/ATAC/60dpf_snATAC_SnapATAC.rds",
dpf210 = "data/ATAC/210dpf_snATAC_SnapATAC.rds"
)
atac_datasets <- lapply(atac_datasets_paths, readRDS)
The authors annotated the RNA dataset of 150 DPF (adult) zebrafish with cell types. I add the annotation to the 150dpf RNA object and then transfer it to the other datasets.
annotation <- setNames(
c(
"stroma 1",
"gill progenitor 1",
"gill cartilage",
"gill cartilage",
"dermal fibroblast",
"gill cartilage",
"gill cartilage",
"periosteum/tendon/ligament",
"teeth",
"perivascular",
"pillar",
"smooth muscle 2",
"gill progenitor 2",
"smooth muscle",
"gill stroma",
"cycling cells",
"tunica media",
"stroma 2",
"hyaline cartilage",
"bone"
),
levels(droplevels(rna_datasets$dpf150$RNA_snn_res.0.8))
)
rna_datasets$dpf150$annotation <- as.factor(unname(
annotation[as.character(rna_datasets$dpf150$RNA_snn_res.0.8)]
))
I plot the annotation to check if it looks correct.
DimPlot(rna_datasets$dpf150, group.by = "annotation", label = T, repel = T) +
NoAxes() +
ggtitle("RNA annotation")
I use the PCA transfer workflow as described in the Seurat
vignette to transfer the annotation from the 150 DPF RNA dataset to
the other RNA datasets. The metadata of the objects then has a column
annotation with the predicted label (highest prediction
score). The prediction score of that label is called
prediction.score.max. Additionally, the metadata contains
columns with the prediction scores for each label.
transfer_anno <- function(dataset) {
transfer_anchors <- FindTransferAnchors(
reference = rna_datasets$dpf150,
query = dataset,
features = VariableFeatures(rna_datasets$dpf150),
reference.assay = "RNA",
query.assay = "RNA"
)
predictions <- TransferData(
anchorset = transfer_anchors,
refdata = rna_datasets$dpf150$annotation,
dims = 1:30
)
predictions <- predictions |>
mutate(
predicted.id = factor(
predicted.id, levels = levels(rna_datasets$dpf150$annotation)
)
) |>
dplyr::rename(
annotation = predicted.id
)
AddMetaData(
dataset,
metadata = predictions
)
}
rna_datasets[1:6] <- lapply(rna_datasets[1:6], transfer_anno)
## Performing PCA on the provided reference using 2000 features as input.
## Warning: Command ScaleData.RNA changing from SeuratCommand to SeuratCommand
## Warning: Command RunPCA.RNA changing from SeuratCommand to SeuratCommand
## Projecting cell embeddings
## Finding neighborhoods
## Finding anchors
## Found 197 anchors
## Finding integration vectors
## Finding integration vector weights
## Predicting cell labels
## Performing PCA on the provided reference using 2000 features as input.
## Warning: Command ScaleData.RNA changing from SeuratCommand to SeuratCommand
## Command RunPCA.RNA changing from SeuratCommand to SeuratCommand
## Projecting cell embeddings
## Finding neighborhoods
## Finding anchors
## Found 304 anchors
## Finding integration vectors
## Finding integration vector weights
## Predicting cell labels
## Performing PCA on the provided reference using 2000 features as input.
## Warning: Command ScaleData.RNA changing from SeuratCommand to SeuratCommand
## Command RunPCA.RNA changing from SeuratCommand to SeuratCommand
## Projecting cell embeddings
## Finding neighborhoods
## Finding anchors
## Found 1909 anchors
## Finding integration vectors
## Finding integration vector weights
## Predicting cell labels
## Performing PCA on the provided reference using 2000 features as input.
## Warning: Command ScaleData.RNA changing from SeuratCommand to SeuratCommand
## Command RunPCA.RNA changing from SeuratCommand to SeuratCommand
## Projecting cell embeddings
## Finding neighborhoods
## Finding anchors
## Found 4245 anchors
## Finding integration vectors
## Finding integration vector weights
## Predicting cell labels
## Performing PCA on the provided reference using 2000 features as input.
## Warning: Command ScaleData.RNA changing from SeuratCommand to SeuratCommand
## Command RunPCA.RNA changing from SeuratCommand to SeuratCommand
## Projecting cell embeddings
## Finding neighborhoods
## Finding anchors
## Found 6698 anchors
## Finding integration vectors
## Finding integration vector weights
## Predicting cell labels
## Performing PCA on the provided reference using 2000 features as input.
## Warning: Command ScaleData.RNA changing from SeuratCommand to SeuratCommand
## Command RunPCA.RNA changing from SeuratCommand to SeuratCommand
## Projecting cell embeddings
## Finding neighborhoods
## Finding anchors
## Found 6459 anchors
## Finding integration vectors
## Finding integration vector weights
## Predicting cell labels
I plot the annotation for all RNA datasets to check if it looks correct.
(DimPlot(rna_datasets$dpf1.5, group.by = "annotation", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("1.5 DPF")) +
(DimPlot(rna_datasets$dpf2, group.by = "annotation", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("2 DPF")) +
(DimPlot(rna_datasets$dpf3, group.by = "annotation", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("3 DPF")) +
(DimPlot(rna_datasets$dpf5, group.by = "annotation", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("5 DPF")) +
(DimPlot(rna_datasets$dpf14, group.by = "annotation", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("14 DPF")) +
(DimPlot(rna_datasets$dpf60, group.by = "annotation", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("60 DPF")) +
(DimPlot(rna_datasets$dpf150, group.by = "annotation", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("150 DPF")) +
plot_layout(ncol = 2)
## Warning: ggrepel: 5 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps
## Warning: ggrepel: 1 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps
ggsave("figures/RNA_annotation.pdf")
## Saving 7.25 x 12 in image
## Warning: ggrepel: 3 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps
The early stages are dominated by cycling cells. We should check if this is expected. There is not much information about this in this paper, the earlier samples are just annotated as mesenchyme. In later stages, more defined cell types appear and the annotation looks reasonable.
We should still take some time to check with literature marker genes.
Now, I will transfer the annotation and clusters from the RNA datasets to the ATAC datasets. I will use the CCA transfer workflow as described in the Seurat vignette. I first try it with the clusters of the 1.5 DPF RNA dataset, to test if it works.
transfer_anchors <- FindTransferAnchors(
reference = rna_datasets$dpf1.5,
query = atac_datasets$dpf1.5,
features = VariableFeatures(rna_datasets$dpf1.5),
reference.assay = "RNA",
query.assay = "ACTIVITY",
reduction = "cca"
)
## Warning: Command ScaleData.RNA changing from SeuratCommand to SeuratCommand
## Running CCA
## Merging objects
## Finding neighborhoods
## Finding anchors
## Found 4529 anchors
cluster_predictions <- TransferData(
anchorset = transfer_anchors,
refdata = rna_datasets$dpf1.5$RNA_snn_res.0.8,
weight.reduction = atac_datasets$dpf1.5[["lsi"]],
dims = 2:30
)
## Finding integration vectors
## Finding integration vector weights
## Predicting cell labels
dpf1.5_test <- AddMetaData(
atac_datasets$dpf1.5,
metadata = cluster_predictions
)
dpf1.5_test$predicted.id <- factor(
dpf1.5_test$predicted.id,
levels = c("0", "1", "2", "4", "6", "7", "9", "10")
)
I plot the clusters and the expression/gene activity score of some marker genes that are specific for these clusters to check if the transfer result looks reasonable.
(
DimPlot(rna_datasets$dpf1.5, group.by = "RNA_snn_res.0.8", label = T) +
ggtitle("RNA") |
DimPlot(dpf1.5_test, group.by = "predicted.id", label = T) +
ggtitle("ATAC")
) /
(
HexPlot(rna_datasets$dpf1.5, "pitx2", bins = 100) |
HexPlot(dpf1.5_test, "pitx2", bins = 100)
) /
(
HexPlot(rna_datasets$dpf1.5, "hoxd4a", bins = 100) |
HexPlot(dpf1.5_test, "hoxd4a", bins = 100)
) /
(
HexPlot(rna_datasets$dpf1.5, "hand2", bins = 100) |
HexPlot(dpf1.5_test, "hand2", bins = 100)
) /
(
HexPlot(rna_datasets$dpf1.5, "pou3f3a", bins = 100) |
HexPlot(dpf1.5_test, "pou3f3a", bins = 100)
)
ggsave("figures/RNA_ATAC_integration_1.5dpf_expression_activity.pdf")
## Saving 6.5 x 12 in image
This looks reasonable. I now transfer the annotation and the clusters pairwise from each RNA dataset to the corresponding ATAC dataset.
Similar to the annotation transfer in the RNA, the metadata of the
objects then has a column annotation with the predicted
label (highest prediction score) and a column RNA_cluster
with the predicted cluster from the RNA data. The prediction scores of
these labels are called annotation_prediction.score.max and
RNA_cluster_prediction.score.max, respectively.
Additionally, the metadata contains columns with the prediction scores
for each label.
transfer_anno_to_ATAC <- function(dataset_atac, dataset_rna) {
transfer_anchors <- FindTransferAnchors(
reference = dataset_rna,
query = dataset_atac,
features = VariableFeatures(dataset_rna),
reference.assay = "RNA",
query.assay = "ACTIVITY",
reduction = "cca"
)
cluster_predictions <- TransferData(
anchorset = transfer_anchors,
refdata = dataset_rna$RNA_snn_res.0.8,
weight.reduction = dataset_atac[["lsi"]],
dims = 2:30
) |>
mutate(
predicted.id = factor(
predicted.id, levels = levels(dataset_rna$RNA_snn_res.0.8)
)
) |>
dplyr::rename(
RNA_cluster = predicted.id
) |>
dplyr::rename_with(
.fn = function(x) sub("prediction", "RNA_cluster_prediction", x)
)
annotation_predictions <- TransferData(
anchorset = transfer_anchors,
refdata = dataset_rna$annotation,
weight.reduction = dataset_atac[["lsi"]],
dims = 2:30
) |>
mutate(
predicted.id = factor(
predicted.id, levels = levels(dataset_rna$annotation)
)
) |>
dplyr::rename(
annotation = predicted.id
) |>
dplyr::rename_with(
.fn = function(x) sub("prediction", "annotation_prediction", x)
)
dataset_atac <- AddMetaData(
dataset_atac,
metadata = cluster_predictions
)
dataset_atac <- AddMetaData(
dataset_atac,
metadata = annotation_predictions
)
dataset_atac
}
atac_datasets <- Map(transfer_anno_to_ATAC, atac_datasets, rna_datasets)
## Warning: Command ScaleData.RNA changing from SeuratCommand to SeuratCommand
## Running CCA
## Merging objects
## Finding neighborhoods
## Finding anchors
## Found 4529 anchors
## Finding integration vectors
## Finding integration vector weights
## Predicting cell labels
## Finding integration vectors
## Finding integration vector weights
## Predicting cell labels
## Warning: Command ScaleData.RNA changing from SeuratCommand to SeuratCommand
## Running CCA
## Merging objects
## Finding neighborhoods
## Finding anchors
## Found 6963 anchors
## Finding integration vectors
## Finding integration vector weights
## Predicting cell labels
## Finding integration vectors
## Finding integration vector weights
## Predicting cell labels
## Warning: Command ScaleData.RNA changing from SeuratCommand to SeuratCommand
## Running CCA
## Merging objects
## Finding neighborhoods
## Finding anchors
## Found 7208 anchors
## Finding integration vectors
## Finding integration vector weights
## Predicting cell labels
## Finding integration vectors
## Finding integration vector weights
## Predicting cell labels
## Warning: Command ScaleData.RNA changing from SeuratCommand to SeuratCommand
## Running CCA
## Merging objects
## Finding neighborhoods
## Finding anchors
## Found 6387 anchors
## Finding integration vectors
## Finding integration vector weights
## Predicting cell labels
## Finding integration vectors
## Finding integration vector weights
## Predicting cell labels
## Warning: Command ScaleData.RNA changing from SeuratCommand to SeuratCommand
## Running CCA
## Merging objects
## Finding neighborhoods
## Finding anchors
## Found 9741 anchors
## Finding integration vectors
## Finding integration vector weights
## Predicting cell labels
## Finding integration vectors
## Finding integration vector weights
## Predicting cell labels
## Warning: Command ScaleData.RNA changing from SeuratCommand to SeuratCommand
## Running CCA
## Merging objects
## Finding neighborhoods
## Finding anchors
## Found 3782 anchors
## Finding integration vectors
## Finding integration vector weights
## Predicting cell labels
## Finding integration vectors
## Finding integration vector weights
## Predicting cell labels
## Warning: Command ScaleData.RNA changing from SeuratCommand to SeuratCommand
## Running CCA
## Merging objects
## Finding neighborhoods
## Finding anchors
## Found 4410 anchors
## Finding integration vectors
## Finding integration vector weights
## Predicting cell labels
## Finding integration vectors
## Finding integration vector weights
## Predicting cell labels
I plot the results for all datasets to check if the transfer worked well.
(DimPlot(rna_datasets$dpf1.5, group.by = "RNA_snn_res.0.8", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("RNA 1.5 DPF")) +
(DimPlot(atac_datasets$dpf1.5, group.by = "RNA_cluster", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("ATAC 1.5 DPF")) +
(DimPlot(rna_datasets$dpf2, group.by = "RNA_snn_res.0.8", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("RNA 2 DPF")) +
(DimPlot(atac_datasets$dpf2, group.by = "RNA_cluster", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("ATAC 2 DPF")) +
(DimPlot(rna_datasets$dpf3, group.by = "RNA_snn_res.0.8", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("RNA 3 DPF")) +
(DimPlot(atac_datasets$dpf3, group.by = "RNA_cluster", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("ATAC 3 DPF")) +
(DimPlot(rna_datasets$dpf5, group.by = "RNA_snn_res.0.8", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("RNA 5 DPF")) +
(DimPlot(atac_datasets$dpf5, group.by = "RNA_cluster", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("ATAC 5 DPF")) +
(DimPlot(rna_datasets$dpf14, group.by = "RNA_snn_res.0.8", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("RNA 14 DPF")) +
(DimPlot(atac_datasets$dpf14, group.by = "RNA_cluster", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("ATAC 14 DPF")) +
(DimPlot(rna_datasets$dpf60, group.by = "RNA_snn_res.0.8", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("RNA 60 DPF")) +
(DimPlot(atac_datasets$dpf60, group.by = "RNA_cluster", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("ATAC 60 DPF")) +
(DimPlot(rna_datasets$dpf150, group.by = "RNA_snn_res.0.8", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("RNA 150 DPF")) +
(DimPlot(atac_datasets$dpf210, group.by = "RNA_cluster", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("ATAC 210 DPF")) +
plot_layout(ncol = 2)
ggsave("figures/RNA_ATAC_integration_clusters.pdf")
## Saving 7.25 x 18 in image
(DimPlot(rna_datasets$dpf1.5, group.by = "annotation", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("RNA 1.5 DPF")) +
(DimPlot(atac_datasets$dpf1.5, group.by = "annotation", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("ATAC 1.5 DPF")) +
(DimPlot(rna_datasets$dpf2, group.by = "annotation", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("RNA 2 DPF")) +
(DimPlot(atac_datasets$dpf2, group.by = "annotation", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("ATAC 2 DPF")) +
(DimPlot(rna_datasets$dpf3, group.by = "annotation", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("RNA 3 DPF")) +
(DimPlot(atac_datasets$dpf3, group.by = "annotation", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("ATAC 3 DPF")) +
(DimPlot(rna_datasets$dpf5, group.by = "annotation", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("RNA 5 DPF")) +
(DimPlot(atac_datasets$dpf5, group.by = "annotation", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("ATAC 5 DPF")) +
(DimPlot(rna_datasets$dpf14, group.by = "annotation", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("RNA 14 DPF")) +
(DimPlot(atac_datasets$dpf14, group.by = "annotation", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("ATAC 14 DPF")) +
(DimPlot(rna_datasets$dpf60, group.by = "annotation", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("RNA 60 DPF")) +
(DimPlot(atac_datasets$dpf60, group.by = "annotation", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("ATAC 60 DPF")) +
(DimPlot(rna_datasets$dpf150, group.by = "annotation", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("RNA 150 DPF")) +
(DimPlot(atac_datasets$dpf210, group.by = "annotation", label = T, repel = T) + NoAxes() + NoLegend() + ggtitle("ATAC 210 DPF")) +
plot_layout(ncol = 2)
## Warning: ggrepel: 5 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps
## Warning: ggrepel: 3 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps
ggsave("figures/RNA_ATAC_integration_annotation.pdf")
## Saving 7.25 x 18 in image
## Warning: ggrepel: 4 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps
## Warning: ggrepel: 1 unlabeled data points (too many overlaps). Consider
## increasing max.overlaps
I save the Seurat objects as lists of objects, for the RNA and ATAC datasets, respectively.
saveRDS(rna_datasets, "saved_data/rna_datasets_list.rds")
saveRDS(atac_datasets, "saved_data/atac_datasets_list.rds")
I export the metadata of the RNA and ATAC datasets as TSV files, with
the cell names as first column. The metadata contains the (transferred)
annotation and the original clusters (RNA_snn_res.0.8) for
the RNA datasets, and the transferred annotation and RNA clusters for
the ATAC datasets.
walk(names(rna_datasets), function(name) {
write.table(
rna_datasets[[name]]@meta.data |>
rownames_to_column(var = "cell"),
file = paste0("saved_data/rna_", name, "_metadata.tsv"),
sep = "\t",
quote = F,
row.names = F
)
})
walk(names(atac_datasets), function(name) {
write.table(
atac_datasets[[name]]@meta.data |>
rownames_to_column(var = "cell"),
file = paste0("saved_data/atac_", name, "_metadata.tsv"),
sep = "\t",
quote = F,
row.names = F
)
})
sessionInfo()
## R version 4.3.3 (2024-02-29)
## Platform: x86_64-conda-linux-gnu (64-bit)
## Running under: Ubuntu 24.04.2 LTS
##
## Matrix products: default
## BLAS/LAPACK: /work/ntrost/miniconda3/envs/r4Seurat5/lib/libopenblasp-r0.3.28.so; LAPACK version 3.12.0
##
## locale:
## [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
## [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
## [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
## [7] LC_PAPER=en_US.UTF-8 LC_NAME=C
## [9] LC_ADDRESS=C LC_TELEPHONE=C
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
##
## time zone: Etc/UTC
## tzcode source: system (glibc)
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] hexpression_1.0.1 patchwork_1.3.0 Signac_1.14.0 Seurat_5.1.0
## [5] SeuratObject_5.0.2 sp_2.1-4 lubridate_1.9.4 forcats_1.0.0
## [9] stringr_1.5.1 dplyr_1.1.4 purrr_1.0.2 readr_2.1.5
## [13] tidyr_1.3.1 tibble_3.2.1 ggplot2_3.5.1 tidyverse_2.0.0
##
## loaded via a namespace (and not attached):
## [1] RColorBrewer_1.1-3 rstudioapi_0.17.1 jsonlite_1.8.9
## [4] magrittr_2.0.3 spatstat.utils_3.1-1 farver_2.1.2
## [7] rmarkdown_2.29 ragg_1.3.3 zlibbioc_1.48.0
## [10] vctrs_0.6.5 ROCR_1.0-11 Rsamtools_2.18.0
## [13] spatstat.explore_3.3-3 RCurl_1.98-1.16 RcppRoll_0.3.1
## [16] htmltools_0.5.8.1 sass_0.4.9 sctransform_0.4.1
## [19] parallelly_1.40.1 KernSmooth_2.23-24 bslib_0.8.0
## [22] htmlwidgets_1.6.4 ica_1.0-3 plyr_1.8.9
## [25] plotly_4.10.4 zoo_1.8-12 cachem_1.1.0
## [28] igraph_2.0.3 mime_0.12 lifecycle_1.0.4
## [31] pkgconfig_2.0.3 Matrix_1.6-5 R6_2.5.1
## [34] fastmap_1.2.0 GenomeInfoDbData_1.2.11 fitdistrplus_1.2-1
## [37] future_1.34.0 shiny_1.10.0 digest_0.6.37
## [40] colorspace_2.1-1 S4Vectors_0.40.2 tensor_1.5
## [43] RSpectra_0.16-2 irlba_2.3.5.1 textshaping_0.3.7
## [46] GenomicRanges_1.54.1 labeling_0.4.3 progressr_0.15.1
## [49] fansi_1.0.6 spatstat.sparse_3.1-0 timechange_0.3.0
## [52] httr_1.4.7 polyclip_1.10-7 abind_1.4-5
## [55] compiler_4.3.3 withr_3.0.2 BiocParallel_1.36.0
## [58] viridis_0.6.5 fastDummies_1.7.4 hexbin_1.28.5
## [61] MASS_7.3-60.0.1 tools_4.3.3 lmtest_0.9-40
## [64] httpuv_1.6.15 future.apply_1.11.2 goftest_1.2-3
## [67] glue_1.8.0 nlme_3.1-165 promises_1.3.2
## [70] grid_4.3.3 Rtsne_0.17 cluster_2.1.8
## [73] reshape2_1.4.4 generics_0.1.3 gtable_0.3.6
## [76] spatstat.data_3.1-4 tzdb_0.4.0 data.table_1.15.2
## [79] hms_1.1.3 XVector_0.42.0 utf8_1.2.4
## [82] BiocGenerics_0.48.1 spatstat.geom_3.3-4 RcppAnnoy_0.0.22
## [85] ggrepel_0.9.6 RANN_2.6.2 pillar_1.9.0
## [88] spam_2.11-0 RcppHNSW_0.6.0 later_1.4.1
## [91] splines_4.3.3 lattice_0.22-6 survival_3.7-0
## [94] deldir_2.0-4 tidyselect_1.2.1 Biostrings_2.70.1
## [97] miniUI_0.1.1.1 pbapply_1.7-2 knitr_1.49
## [100] gridExtra_2.3 IRanges_2.36.0 scattermore_1.2
## [103] stats4_4.3.3 xfun_0.49 matrixStats_1.4.1
## [106] stringi_1.8.4 lazyeval_0.2.2 yaml_2.3.10
## [109] evaluate_1.0.1 codetools_0.2-20 cli_3.6.3
## [112] uwot_0.1.16 systemfonts_1.1.0 xtable_1.8-4
## [115] reticulate_1.40.0 munsell_0.5.1 jquerylib_0.1.4
## [118] Rcpp_1.0.13-1 GenomeInfoDb_1.38.1 globals_0.16.3
## [121] spatstat.random_3.3-2 png_0.1-8 spatstat.univar_3.1-1
## [124] parallel_4.3.3 dotCall64_1.2 bitops_1.0-9
## [127] listenv_0.9.1 viridisLite_0.4.2 scales_1.3.0
## [130] ggridges_0.5.6 crayon_1.5.3 leiden_0.4.3.1
## [133] rlang_1.1.4 fastmatch_1.1-6 cowplot_1.1.3